<<<<<<< HEAD
﻿using System;
using System.Collections.Generic;
using System.Linq;
=======
﻿using Microsoft.Data.SqlClient;
using Newtonsoft.Json;
using RxxApi.Common.Extensions;
using RxxApi.Common.Helper;
using RxxApi.Model.Entity;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
>>>>>>> 978f3e50234340b2479b3d4d960a10aa408b09d0
using System.Text;
using System.Threading.Tasks;

namespace RxxApi.Common.Seed;

<<<<<<< HEAD
public class DBSeed
{
=======
public  class DBSeed
{

    private static string SeedDataFolder = "Data.json/{0}.tsv";

    /// <summary>
    /// 异步添加种子数据
    /// </summary>
    /// <param name="myContext"></param>
    /// <param name="WebRootPath"></param>
    /// <returns></returns>
    public static async Task SeedAsync(MyContext myContext, string WebRootPath)
    {
        try
        {
            if (string.IsNullOrEmpty(WebRootPath))
            {
                throw new Exception("获取wwwroot路径时，异常！");
            }

            SeedDataFolder = Path.Combine(WebRootPath, SeedDataFolder);

            Console.WriteLine("************ RxxAdmin DataBase Set *****************");          
            Console.WriteLine($"Master DB ConnectString: {myContext.Db.CurrentConnectionConfig.ConnectionString}");            
            Console.WriteLine();

            // 创建数据库
            Console.WriteLine($"Create Database...");
            myContext.Db.DbMaintenance.CreateDatabase();
            Console.WriteLine($"Database created successfully!");
            // 创建数据库表，遍历指定命名空间下的class，
            // 注意不要把其他命名空间下的也添加进来。
            Console.WriteLine("Create Tables...");

            var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
            var referencedAssemblies = System.IO.Directory.GetFiles(path, "RxxApi.Model.dll")
               .Select(Assembly.LoadFrom).ToArray();
            var modelTypes = referencedAssemblies
               .SelectMany(a => a.DefinedTypes)
               .Select(type => type.AsType())
               .Where(x => x.IsClass && x.Namespace is "RxxApi.Model.Entity")
               .ToList();
            modelTypes.ForEach(t =>
            {
                // 这里只支持添加表，不支持删除
                // 如果想要删除，数据库直接右键删除，或者联系SqlSugar作者；
                if (!myContext.Db.DbMaintenance.IsAnyTable(t.Name))
                {
                    Console.WriteLine(t.Name);
                    myContext.Db.CodeFirst.SplitTables().InitTables(t);
                }
            });
            Console.WriteLine($"Tables created successfully!");
            Console.WriteLine();
            JsonSerializerSettings setting = new JsonSerializerSettings();
            JsonConvert.DefaultSettings = new Func<JsonSerializerSettings>(() =>
            {
                //日期类型默认格式化处理
                setting.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
                setting.DateFormatString = "yyyy-MM-dd HH:mm:ss";

                //空值处理
                setting.NullValueHandling = NullValueHandling.Ignore;

                //高级用法九中的Bool类型转换 设置
                //setting.Converters.Add(new BoolConvert("是,否"));

                return setting;
            });
            Console.WriteLine($"Seeding database data...");
            #region SysUser

            if (!await myContext.Db.Queryable<SysUser>().AnyAsync())
            {
                var data = JsonConvert.DeserializeObject<List<SysUser>>(
                    FileHelper.ReadFile(string.Format(SeedDataFolder, "SysUser"), Encoding.UTF8), setting);

                myContext.GetEntityDB<SysUser>().InsertRange(data);
                Console.WriteLine("Table:SysUser created success!");
            }
            else
            {
                Console.WriteLine("Table:SysUser already exists...");
            }

            #endregion
            #region SysRole

            if (!await myContext.Db.Queryable<SysRole>().AnyAsync())
            {
                var data = JsonConvert.DeserializeObject<List<SysRole>>(
                    FileHelper.ReadFile(string.Format(SeedDataFolder, "SysRole"), Encoding.UTF8), setting);

                myContext.GetEntityDB<SysRole>().InsertRange(data);
                Console.WriteLine("Table:SysRole created success!");
            }
            else
            {
                Console.WriteLine("Table:SysRole already exists...");
            }

            #endregion
            #region SysUserRole

            if (!await myContext.Db.Queryable<SysUserRole>().AnyAsync())
            {
                var data = JsonConvert.DeserializeObject<List<SysUserRole>>(
                    FileHelper.ReadFile(string.Format(SeedDataFolder, "SysUserRole"), Encoding.UTF8), setting);

                myContext.GetEntityDB<SysUserRole>().InsertRange(data);
                Console.WriteLine("Table:SysUserRole created success!");
            }
            else
            {
                Console.WriteLine("Table:SysUserRole already exists...");
            }

            #endregion
            #region SysMenu

            if (!await myContext.Db.Queryable<SysMenu>().AnyAsync())
            {
                var data = JsonConvert.DeserializeObject<List<SysMenu>>(
                    FileHelper.ReadFile(string.Format(SeedDataFolder, "SysMenu"), Encoding.UTF8), setting);

                myContext.GetEntityDB<SysMenu>().InsertRange(data);
                Console.WriteLine("Table:SysMenu created success!");
            }
            else
            {
                Console.WriteLine("Table:SysMenu already exists...");
            }

            #endregion
            #region SysRoleMenu

            if (!await myContext.Db.Queryable<SysRoleMenu>().AnyAsync())
            {
                var data = JsonConvert.DeserializeObject<List<SysRoleMenu>>(
                    FileHelper.ReadFile(string.Format(SeedDataFolder, "SysRoleMenu"), Encoding.UTF8), setting);

                myContext.GetEntityDB<SysRoleMenu>().InsertRange(data);
                Console.WriteLine("Table:SysRoleMenu created success!");
            }
            else
            {
                Console.WriteLine("Table:SysRoleMenu already exists...");
            }

            #endregion
            //种子初始化
            await SeedDataAsync(myContext.Db);
            Console.WriteLine($"Done seeding database!");           
            Console.WriteLine();
        }
        catch (Exception ex)
        {
            throw new Exception(
                $"1、若是Mysql,查看常见问题:https://github.com/anjoy8/Blog.Core/issues/148#issue-776281770 \n" +
                $"2、若是Oracle,查看常见问题:https://github.com/anjoy8/Blog.Core/issues/148#issuecomment-752340231 \n" +
                "3、其他错误：" + ex.Message);
        }
    }

    /// <summary>
    /// 种子初始化数据
    /// </summary>
    /// <param name="myContext"></param>
    /// <returns></returns>
    private static async Task SeedDataAsync(ISqlSugarClient db)
    {
        // 获取所有种子配置-初始化数据
        var seedDataTypes = AssemblysExtensions.GetAllAssemblies().SelectMany(s => s.DefinedTypes)
           .Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass)
           .Where(u =>
           {
               var esd = u.GetInterfaces()
                      .FirstOrDefault(i => i.HasImplementedRawGeneric(typeof(IEntitySeedData<>)));
               if (esd is null)
               {
                   return false;
               }

               return false;
           });

        if (!seedDataTypes.Any()) return;
        foreach (var seedType in seedDataTypes)
        {
            dynamic instance = Activator.CreateInstance(seedType);
            //初始化数据
            {
                var seedData = instance.InitSeedData();
                if (seedData != null && Enumerable.Any(seedData))
                {
                    var entityType = seedType.GetInterfaces().First().GetGenericArguments().First();
                    var entity = db.EntityMaintenance.GetEntityInfo(entityType);

                    if (!await db.Queryable(entity.DbTableName, "").AnyAsync())
                    {
                        await db.Insertable(Enumerable.ToList(seedData)).ExecuteCommandAsync();
                        Console.WriteLine($"Table:{entity.DbTableName} init success!");
                    }
                }
            }

            //种子数据
            {
                var seedData = instance.SeedData();
                if (seedData != null && Enumerable.Any(seedData))
                {
                    var entityType = seedType.GetInterfaces().First().GetGenericArguments().First();
                    var entity = db.EntityMaintenance.GetEntityInfo(entityType);

                    await db.Storageable(Enumerable.ToList(seedData)).ExecuteCommandAsync();
                    Console.WriteLine($"Table:{entity.DbTableName} seedData success!");
                }
            }

            //自定义处理
            {
                await instance.CustomizeSeedData(db);
            }
        }
    }
>>>>>>> 978f3e50234340b2479b3d4d960a10aa408b09d0
}
